﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Net.Mail;
using System.Text;
using System.Web.Security;
using Medianamik.Core;
using Medianamik.Core.Security;
using Medianamik.UI.Web.Approbation.Data;
using NLog;

namespace Medianamik.Approbation.Tasks
{
    class Program
    {
        static Logger _logger = LogManager.GetLogger("Synchronizer");

        public static void Main(string[] args)
        {
            try
            {
                var argument = "";

                if (args.Length > 0)
                    argument = args[0];

                switch (argument)
                {
                    case "/sendapprobationemails":
                        //TODO:
                        break;
                    default:
                        try
                        {
                            ExecuteManual();
                        }
                        catch (Exception exception)
                        {
                            Console.Write("\nUne erreur est survenue : " + exception +
                                "\nAppuyez sur une touche pour retourner au menu...");
                            Console.ReadKey();
                            ExecuteManual();
                        }

                        break;
                }
            }
            catch (Exception ex)
            {
                Console.Write("\nUne erreur est survenue : " + ex +
                    "\nAppuyez sur une touche pour quitter...");
                Console.ReadKey();
            }
        }

        private static void ExecuteManual()
        {
            var answer = "";

            while (answer == "")
            {
                answer = DisplayOperations();

                switch (answer)
                {
                    case "1":
                        answer = ConfirmAction("Êtes-vous certain de vouloir envoyer les courriels d'approbation ? (O/N) : ",
                                SendApprobationEmails);
                        break;
                    case "2":
                        Console.Write("\n\nÊtes-vous certain de vouloir quitter ? (O/N) : ");

                        answer = Console.ReadKey().KeyChar.ToString();

                        if (!answer.Equals("o", StringComparison.OrdinalIgnoreCase))
                        {
                            answer = "";
                        }

                        break;
                    default:
                        Console.Write("\n\nL'opération spécifiée n'est pas disponible...\n");
                        answer = "";
                        break;
                }
            }
        }

        private static void SendApprobationEmails()
        {
            var allGroups = SecurityManager.AllGroups.ToList();
            var approbationRepository = new ApprobationRepository();

            var groupsWithPendingApprobations = new List<Group>();
            foreach (var group in allGroups)
            {
                var approbationCount = approbationRepository
                    .GetPendingApprobationsCount(null, group.ID.ToString(), true, false);

                if (approbationCount > 0)
                {
                    groupsWithPendingApprobations.Add(group);
                }
            }

            if (groupsWithPendingApprobations.Count > 0)
            {
                var userIds = SecurityManager.GetUsersInGroups(groupsWithPendingApprobations.Select(g => g.GroupName));
                var usersWithPendingApprobation = new List<MembershipUser>();
                foreach (var userId in userIds)
                {
                    usersWithPendingApprobation.Add(Membership.GetUser(userId));
                }

                SendApprobationEmailToUsers(usersWithPendingApprobation);
            }
        }

        private static void SendApprobationEmailToUsers(List<MembershipUser> usersWithPendingApprobation)
        {
            // debug temporaire: host="192.168.0.164" (mercure3)
            var client = new SmtpClient();
            using (var message = new MailMessage())
            {
                foreach (var user in usersWithPendingApprobation)
                {
                    message.To.Add(new MailAddress(user.Email, user.UserName));
                }

                // todo from
                message.From = new MailAddress("approbations@medianamik.com");
                // todo objet
                message.Subject = "Vous avez du contenu en attente d'approbation";

                message.IsBodyHtml = true;
                message.SubjectEncoding = Encoding.GetEncoding(ConfigurationManager.AppSettings["EncodingType"]);
                message.BodyEncoding = Encoding.GetEncoding(ConfigurationManager.AppSettings["EncodingType"]);

                // todo body html
                // todo lien vers domain + /medianamik/aapprobation/approbationlist.aspx
                message.Body =
                    "<h1>Vous avez du contenu en attente d'approbation</h1><p><a href=\"javascript:void(0);\">Gestion des approbations</a></p>";

                client.Send(message);
            }
        }

        private static string ConfirmAction(string message, Action action)
        {
            Console.Write("\n\n" + message);

            if (Console.ReadKey().KeyChar.ToString().Equals("o", StringComparison.OrdinalIgnoreCase))
            {
                action.Invoke();
            }

            return "";
        }

        private static string DisplayOperations()
        {
            Console.WriteLine("\n\nVeuillez choisir l'une des opérations suivantes : ");

            Console.Write("\n\t- Appuyez sur 1 pour envoyer les courriels d'approbation.");
            Console.Write("\n\t- Appuyez sur 2 pour quitter.");
            Console.Write("\n\nAppuyez sur le nombre correspondent à l'opération à effectuer : ");

            return Console.ReadKey().KeyChar.ToString();
        }
    }
}
